library ieee;

use ieee.std_logic_1164.all;
--use ieee.numeric_std.all;

use work.cpu_utils.all;

entity reg_file is
generic (
	address_size : integer := 5; -- number of address bits
	register_size : integer := 32;
	Tpd : Time := unit_delay
	);
port (
	clock : in bit;
	source_address_1 : in bit_vector(address_size-1 downto 0);
	data_1 : out bit_vector(register_size-1 downto 0);
	source_address_2 : in bit_vector(address_size-1 downto 0);
	data_2 : out bit_vector(register_size-1 downto 0);
	destination_address : in bit_vector(address_size-1 downto 0);
	data_3 : in bit_vector (register_size-1 downto 0);
	H_in, L_in : in bit);
end reg_file;

architecture reg_file_arh of reg_file is
subtype reg is bit_vector(register_size-1 downto 0);
		type register_array is array (0 to 2**address_size-1) of reg;
		shared variable registers : register_array;
begin
  
  process(source_address_1)
  begin
  -- output 1
			data_1 <= registers(to_integer(source_address_1)) after Tpd;
	end process;		
		
	process(source_address_2)
  begin	
	
			-- output 2
			data_2 <= registers(to_integer(source_address_2)) after Tpd;
	
	end process;				
			
	reg_file_process: 
		process(
			clock,
			H_in, L_in,
			source_address_1, source_address_2, 
			destination_address,
			data_3
			)
		
	begin
		if clock'event and clock = '1' then
			
			-- input
			if H_in = '1' then
				registers(to_integer(destination_address))(register_size-1 downto register_size/2) 
					:= data_3(register_size-1 downto register_size/2);
			end if;
			if L_in = '1' then
				registers(to_integer(destination_address))(register_size/2-1 downto 0) 
					:= data_3(register_size/2-1 downto 0);
			end if;			
		end if;
	end process reg_file_process;
end reg_file_arh;